package cn.com.manager.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricProcessInstanceQuery;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricTaskInstanceQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.runtime.ProcessInstanceQuery;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

import cn.com.manager.dao.PurchaseOrderAuditMapper;
import cn.com.manager.dao.PurchaseOrderDetailMapper;
import cn.com.manager.dao.PurchaseOrderMapper;
import cn.com.manager.page.PageInfo;
import cn.com.manager.pojo.PurchaseOrder;
import cn.com.manager.pojo.PurchaseOrderDetail;
import cn.com.manager.pojo.PurchaseOrderDetailExample;
import cn.com.manager.pojo.PurchaseOrderExample;
import cn.com.manager.pojo.PurchaseOrderExample.Criteria;
import cn.com.manager.pojo.vo.PurchaseOrderVo;
import cn.com.manager.pojo.vo.PurchaseOrderWithProcess;
import cn.com.manager.service.PurchaseService;
import cn.com.manager.utility.ProcessEnum;

@Service
public class PurchaseServiceImpl implements PurchaseService {
	@Autowired
	private PurchaseOrderMapper purchaseOrderMapper;
	@Autowired
	private PurchaseOrderDetailMapper purchaseOrderDetailMapper;
	@Autowired
	private PurchaseOrderAuditMapper purchaseOrderAuditMapper;
	@Autowired
	private RuntimeService runtimeService;
	@Autowired
	private TaskService taskService;
	@Autowired
	private HistoryService historyService;
	@Autowired
	private IdentityService identityService;

	@Override
	@Transactional(value = "transactionManager", propagation = Propagation.REQUIRED)
	public void addPurchaseOrder(PurchaseOrder purchaseOrder) {
		if (StringUtils.isNotBlank(purchaseOrder.getId())) {
			purchaseOrderMapper.updateByPrimaryKeySelective(purchaseOrder);
			PurchaseOrderDetailExample example = new PurchaseOrderDetailExample();
			example.createCriteria().andOrderIdEqualTo(purchaseOrder.getId());
			purchaseOrderDetailMapper.deleteByExample(example);
		} else {
			purchaseOrderMapper.insertSelective(purchaseOrder);
		}
		List<PurchaseOrderDetail> purchaseOrderDetails = purchaseOrder.getPurchaseOrderDetails();
		purchaseOrderDetails.forEach(bean -> {
			bean.setOrderId(purchaseOrder.getId());
			purchaseOrderDetailMapper.insertSelective(bean);
		});
	}

	@Override
	public PurchaseOrderWithProcess getPurchaseOrderInfo(String orderId) {
		PurchaseOrder purchaseOrder = purchaseOrderMapper.selectByPrimaryKey(orderId);
		PurchaseOrderDetailExample example = new PurchaseOrderDetailExample();
		example.createCriteria().andOrderIdEqualTo(purchaseOrder.getId());
		List<PurchaseOrderDetail> details = purchaseOrderDetailMapper.selectByExample(example);
		purchaseOrder.setPurchaseOrderDetails(details);
		
		PurchaseOrderWithProcess purchaseOrderWithProcess = new PurchaseOrderWithProcess();
		BeanUtils.copyProperties(purchaseOrder, purchaseOrderWithProcess);
		return purchaseOrderWithProcess;
	}

	@Override
	public void createPurchaseOrderInstance(String purchaseOrderId,String user) {
		//设置流程发起人
		identityService.setAuthenticatedUserId(user);
		//启动流程实例
		ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(ProcessEnum.PURCHASE_ORDER_DEFINITION_KEY.getKeyValue(), purchaseOrderId);
		PurchaseOrder purchaseOrder = purchaseOrderMapper.selectByPrimaryKey(purchaseOrderId);
		purchaseOrder.setInstanceId(processInstance.getProcessInstanceId());
		purchaseOrder.setCreateTime(new Date());
		purchaseOrderMapper.updateByPrimaryKeySelective(purchaseOrder);
	}

	@Override
	public List<PurchaseOrderWithProcess> getPurchaseOrderTaskList(PurchaseOrderWithProcess purchaseOrderWithProcess,String userId,PageInfo pageInfo) {
		TaskQuery taskQuery = taskService.createTaskQuery().processDefinitionKey(ProcessEnum.PURCHASE_ORDER_DEFINITION_KEY.getKeyValue())
				.taskAssignee(userId);
		pageInfo.setCount(taskQuery.list().size());
		
		List<Task> list = new ArrayList<Task>();
		if(pageInfo.getCount()>0){			
			list = taskQuery.orderByTaskCreateTime().desc().listPage(pageInfo.getOffset(), pageInfo.getOffset()+pageInfo.getPageSize());
		}
		List<PurchaseOrderWithProcess> results = new ArrayList<PurchaseOrderWithProcess>();
		for(Task task : list){
			PurchaseOrderWithProcess bean = new PurchaseOrderWithProcess();
			bean.setTaskId(task.getId());
			bean.setTaskDefinitionKey(task.getTaskDefinitionKey());
			bean.setTaskName(task.getName());
			bean.setAssignee(task.getAssignee());
			
			ProcessInstance instance = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
			PurchaseOrder orderInfo = purchaseOrderMapper.selectByPrimaryKey(instance.getBusinessKey());
			BeanUtils.copyProperties(orderInfo, bean);
			
			results.add(bean);
		}
		return results;
	}

	@Override
	public List<PurchaseOrder> getPurchaseOrderList(PurchaseOrder purchaseOrder, String userId,PageInfo pageInfo) {
		PurchaseOrderExample example = new PurchaseOrderExample();
		PurchaseOrderExample.Criteria criteria = example.createCriteria();
		if (purchaseOrder != null) {
			if (StringUtils.isNoneBlank(purchaseOrder.getTitle())) {
				criteria.andTitleLike("%" + purchaseOrder.getTitle() + "%");
			}
			if (StringUtils.isNoneBlank(purchaseOrder.getId())){
				criteria.andIdEqualTo(purchaseOrder.getId());
			}
		}
		criteria.andCreateUserEqualTo(userId);
		if (pageInfo != null) {
			Page<PurchaseOrder> results = PageHelper.startPage(pageInfo.getPageNo(), pageInfo.getPageSize(), true) .doSelectPage(() -> purchaseOrderMapper.selectByExample(example));
			pageInfo.setCount((int) results.getTotal());
			return results.getResult();
		} else {
			return purchaseOrderMapper.selectByExample(example);
		}	
	}

	@Override
	public void submitPurchaseOrder(String taskId, String userId) {
		Task task = taskService.createTaskQuery().taskAssignee(userId).taskId(taskId).singleResult();
		if(task!=null){
			PurchaseOrderWithProcess purchaseOrderWithProcess = new PurchaseOrderWithProcess();
			
			String processInstanceId = task.getProcessInstanceId();
			ProcessInstance instance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
			PurchaseOrder orderInfo = purchaseOrderMapper.selectByPrimaryKey(instance.getBusinessKey());
			BeanUtils.copyProperties(orderInfo, purchaseOrderWithProcess);
			
			Map<String,Object> variable = new HashMap<String,Object>();
			variable.put("order", purchaseOrderWithProcess);
			taskService.complete(task.getId(),variable);
		}
	}

	@Override
	@Transactional(value = "transactionManager", propagation = Propagation.REQUIRED)
	public void auditPurchaseOrder(PurchaseOrderVo purchaseOrderVo) {
		purchaseOrderAuditMapper.insertSelective(purchaseOrderVo.getPurchaseOrderAudit());
		
		if(purchaseOrderVo.getPurchaseOrderAudit().getStatus().equals("0")){
			//若不通过 ，则修改订单状态为未处理的状态
			PurchaseOrder order = new PurchaseOrder();
			order.setId(purchaseOrderVo.getPurchaseOrderWithProcess().getId());
			order.setStatus("");
			updatePurchaseOrderStatus(order);
		}
		Task task = taskService.createTaskQuery().taskId(purchaseOrderVo.getPurchaseOrderWithProcess().getTaskId()).taskAssignee(purchaseOrderVo.getPurchaseOrderAudit().getUserId()).singleResult();
		if(task!=null){
			Map<String,Object> variable = new HashMap<String,Object>();
			if(StringUtils.equals(purchaseOrderVo.getPurchaseOrderAudit().getAuditType(), "departmentAudit")){
				variable.put("departmentAudit", purchaseOrderVo.getPurchaseOrderAudit());
			}else if(StringUtils.equals(purchaseOrderVo.getPurchaseOrderAudit().getAuditType(), "managerAudit")){
				variable.put("managerAudit", purchaseOrderVo.getPurchaseOrderAudit());
			}else if(StringUtils.equals(purchaseOrderVo.getPurchaseOrderAudit().getAuditType(), "accountAudit")){
				variable.put("accountAudit", purchaseOrderVo.getPurchaseOrderAudit());
			}
			taskService.complete(purchaseOrderVo.getPurchaseOrderWithProcess().getTaskId(),variable);
		}
	}

	@Override
	public List<PurchaseOrderWithProcess> findPurchaseOrderInstance(PurchaseOrderWithProcess purchaseOrderWithProcess, PageInfo pageInfo,String user) {
		//查询当前用户正在审核的采购单，目的是获取实例id
		PurchaseOrderExample example = new PurchaseOrderExample();
		Criteria criteria = example.createCriteria();
		criteria.andCreateUserEqualTo(user).andStatusEqualTo("1");
		if(purchaseOrderWithProcess!=null){
			if(StringUtils.isNotBlank(purchaseOrderWithProcess.getId())){
				criteria.andIdEqualTo(purchaseOrderWithProcess.getId());
			}
			if(StringUtils.isNotBlank(purchaseOrderWithProcess.getTitle())){
				criteria.andTitleLike("%"+purchaseOrderWithProcess.getTitle()+"%");
			}
			if(StringUtils.isNotBlank(purchaseOrderWithProcess.getInstanceId())){
				criteria.andInstanceIdEqualTo(purchaseOrderWithProcess.getInstanceId());
			}
		}
		
		Page<PurchaseOrder> results = PageHelper.startPage(pageInfo.getPageNo(), pageInfo.getPageSize(), true) .doSelectPage(() -> purchaseOrderMapper.selectByExample(example));
		pageInfo.setCount((int) results.getTotal());
		
		List<PurchaseOrderWithProcess> instanceList = new ArrayList<PurchaseOrderWithProcess>();
		for(PurchaseOrder order :results.getResult()){
			String instanceId = order.getInstanceId();//实例ID
			//获取流程实例
			ProcessInstanceQuery query = runtimeService.createProcessInstanceQuery().processDefinitionKey(ProcessEnum.PURCHASE_ORDER_DEFINITION_KEY.getKeyValue());
			query.processInstanceId(instanceId);
			ProcessInstance instance = query.singleResult();
			
			PurchaseOrderWithProcess purchaseOrderProcess = new PurchaseOrderWithProcess();
			purchaseOrderProcess.setActivityId(instance.getActivityId());
			BeanUtils.copyProperties(order, purchaseOrderProcess);
			instanceList.add(purchaseOrderProcess);
		}
		
		return instanceList;
	}

	@Override
	public List<PurchaseOrderWithProcess> findHistoryPurchaseOrderInstance(PurchaseOrderWithProcess purchaseOrderWithProcess, PageInfo pageInfo, String user) {
		// 查询当前用户已完成的采购单，目的是获取实例id
		PurchaseOrderExample example = new PurchaseOrderExample();
		Criteria criteria = example.createCriteria();
		criteria.andCreateUserEqualTo(user).andStatusEqualTo("2");
		if (purchaseOrderWithProcess != null) {
			if (StringUtils.isNotBlank(purchaseOrderWithProcess.getId())) {
				criteria.andIdEqualTo(purchaseOrderWithProcess.getId());
			}
			if (StringUtils.isNotBlank(purchaseOrderWithProcess.getTitle())) {
				criteria.andTitleLike("%" + purchaseOrderWithProcess.getTitle() + "%");
			}
			if (StringUtils.isNotBlank(purchaseOrderWithProcess.getInstanceId())) {
				criteria.andInstanceIdEqualTo(purchaseOrderWithProcess.getInstanceId());
			}
		}

		Page<PurchaseOrder> results = PageHelper.startPage(pageInfo.getPageNo(), pageInfo.getPageSize(), true).doSelectPage(() -> purchaseOrderMapper.selectByExample(example));
		pageInfo.setCount((int) results.getTotal());

		List<PurchaseOrderWithProcess> instanceList = new ArrayList<PurchaseOrderWithProcess>();
		for (PurchaseOrder order : results.getResult()) {
			String instanceId = order.getInstanceId();// 实例ID
			// 获取流程实例
			HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().processDefinitionKey(ProcessEnum.PURCHASE_ORDER_DEFINITION_KEY.getKeyValue()).finished();
			query.processInstanceId(instanceId);
			HistoricProcessInstance historyInstance = query.singleResult();

			PurchaseOrderWithProcess purchaseOrderProcess = new PurchaseOrderWithProcess();
			purchaseOrderProcess.setProcessInstance_startTime(historyInstance.getStartTime());
			purchaseOrderProcess.setProcessInstance_endTime(historyInstance.getEndTime());
			BeanUtils.copyProperties(order, purchaseOrderProcess);
			instanceList.add(purchaseOrderProcess);
		}
		return instanceList;
	}

	@Override
	public void updatePurchaseOrderStatus(PurchaseOrder purchaseOrder) {
		PurchaseOrder order = new PurchaseOrder();
		order.setId(purchaseOrder.getId());
		order.setStatus(purchaseOrder.getStatus());
		purchaseOrderMapper.updateByPrimaryKeySelective(order);
	}

	@Override
	public Map<String, Double> getPurchaseOrderCount(PurchaseOrder purchaseOrder) {
		Map<String,Double> params = new HashMap<String,Double>();
		double count = purchaseOrderMapper.countDudget(purchaseOrder);
		params.put("dudget", count);
		return params;
	}

	@Override
	public List<PurchaseOrderWithProcess> findHistoryPurchaseOrderTask(String instanceId) {
		HistoricTaskInstanceQuery historyTaskQuery = historyService.createHistoricTaskInstanceQuery();
		historyTaskQuery.processDefinitionKey(ProcessEnum.PURCHASE_ORDER_DEFINITION_KEY.getKeyValue());
		historyTaskQuery.processInstanceId(instanceId);
		List<HistoricTaskInstance> list = historyTaskQuery.list();
		
		List<PurchaseOrderWithProcess> purchaseOrderWithProcesses = new ArrayList<PurchaseOrderWithProcess>();
		
		for(HistoricTaskInstance instance : list){
			PurchaseOrderWithProcess bean = new PurchaseOrderWithProcess();
			bean.setTaskId(instance.getId());
			bean.setTaskDefinitionKey(instance.getTaskDefinitionKey());
			bean.setTaskName(instance.getName());
			bean.setAssignee(instance.getAssignee());
			bean.setTask_startTime(instance.getStartTime());
			bean.setTask_endTime(instance.getEndTime());
			purchaseOrderWithProcesses.add(bean);
		}
		return purchaseOrderWithProcesses;
	}

	@Override
	public List<PurchaseOrderWithProcess> getCanPurchaseOrderTaskList(PurchaseOrderWithProcess purchaseOrderWithProcess,
			String userId, PageInfo pageInfo) {
		TaskQuery taskQuery = taskService.createTaskQuery().processDefinitionKey(ProcessEnum.PURCHASE_ORDER_DEFINITION_KEY.getKeyValue());
		//获取组任务
		taskQuery.taskCandidateUser(userId);
		pageInfo.setCount(taskQuery.list().size());
		
		List<Task> list = new ArrayList<Task>();
		if(pageInfo.getCount()>0){			
			list = taskQuery.orderByTaskCreateTime().desc().listPage(pageInfo.getOffset(), pageInfo.getOffset()+pageInfo.getPageSize());
		}
		List<PurchaseOrderWithProcess> results = new ArrayList<PurchaseOrderWithProcess>();
		for(Task task : list){
			PurchaseOrderWithProcess bean = new PurchaseOrderWithProcess();
			bean.setTaskId(task.getId());
			bean.setTaskDefinitionKey(task.getTaskDefinitionKey());
			bean.setTaskName(task.getName());
			
			ProcessInstance instance = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
			PurchaseOrder orderInfo = purchaseOrderMapper.selectByPrimaryKey(instance.getBusinessKey());
			BeanUtils.copyProperties(orderInfo, bean);
			
			results.add(bean);
		}
		return results;
	}

	@Override
	public void pickUpTask(String userId,String taskId) {
		TaskQuery taskQuery = taskService.createTaskQuery().processDefinitionKey(ProcessEnum.PURCHASE_ORDER_DEFINITION_KEY.getKeyValue());
		Task task = taskQuery.taskCandidateUser(userId).taskId(taskId).singleResult();
		if(task!=null){
			taskService.claim(taskId, userId);
		}
	}

	@Override
	public void complateTask(String userId, String taskId) {
		TaskQuery taskQuery = taskService.createTaskQuery().processDefinitionKey(ProcessEnum.PURCHASE_ORDER_DEFINITION_KEY.getKeyValue());
		Task task = taskQuery.taskAssignee(userId).taskId(taskId).singleResult();
		if(task!=null){
			taskService.complete(taskId);
		}
	}

}
